package com.ibeetl.code.ch04.reflect;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;

/** jdk7的办法，貌似不行啊
 * @author 公众号 闲谈java开发
 */
public class MethodHandleTool implements ReflectTool {

	MethodHandle handle = null;

	public MethodHandleTool() {
		//模拟缓存
		handle = getMethodHandler(User.class, "name");
	}

	@Override
	public Object getValue(Object target, String attr) {
		//    MethodHandle handle = getMethodHandler(target.getClass(),attr);
		try {
			Object value = handle.invokeExact(target);
			return value;
		} catch (Throwable ex) {
			throw new IllegalArgumentException(ex);
		}

	}


	public MethodHandle getMethodHandler(Class target, String attr) {
		//定义方法的返回值和入参
		MethodType mt = MethodType.methodType(String.class);
		String methodName = buildGetterName(attr);
		MethodHandle mh = null;
		try {
			//查找方法句柄
			MethodHandle orginalMh = MethodHandles.lookup().findVirtual(target, methodName, mt);
			//适配，mh调用的输出输出都是Object
			mh = orginalMh.asType(MethodType.methodType(Object.class, Object.class));
		} catch (NoSuchMethodException | IllegalAccessException e) {
			throw new IllegalArgumentException(e);
		}

		return mh;
	}


	public static void main(String[] args) {
		MethodHandleTool tool = new MethodHandleTool();
		User user = new User();
		user.setName("abc");
		String value = (String) tool.getValue(user, "name");
		System.out.println(value);
	}

}
